package com.cm.dynamic.controller;

/*
 * @ClassName:ClassLoaderController
 * @Description 动态加载jar包文件
 * 使用步骤
 * 1） 先get请求/loadJar加载custom-class-loader-0.0.1-SNAPSHOT.jar这个jar包
 * 2） 再请求/getAll 得到老师信息
 */

import com.cm.dynamic.classloader.context.ClassloaderResponsity;
import com.cm.dynamic.classloader.ModuleClassLoader;
import com.cm.dynamic.util.SpringContextUtil;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping(value = "/loader")
public class ClassLoaderController {

    @GetMapping(value = "/getMapper")
    public String beans(String name) {
        ClassloaderResponsity classloaderResponsity = ClassloaderResponsity.getInstance();
        if (classloaderResponsity.containsClassLoader("custom-class-loader-0.0.1-SNAPSHOT")) {
            ModuleClassLoader classLoader = classloaderResponsity.getClassLoader("custom-class-loader-0.0.1-SNAPSHOT");
            try {
                Class<?> aClass = classLoader.loadClass(name);
            } catch (ClassNotFoundException e) {

            }
            Object bean = SpringContextUtil.getApplicationContext().getBean(name);
            System.out.println(bean);
        }
        return SpringContextUtil.getApplicationContext().getBean(name).toString();
    }


    @GetMapping(value = "/beans")
    public List<Map<String, Object>> beans(){
        return SpringContextUtil.getAllBean();
    }

    @GetMapping(value = "/deleteModule")
    public List<Map<String, Object>> deleteModule(String moduleName){
        if(ClassloaderResponsity.getInstance().containsClassLoader(moduleName)){
            ClassloaderResponsity.getInstance().removeClassLoader(moduleName);
        }
        return beans();
    }

    @GetMapping(value = "/loadJar")
    public List<?> loadJar(String jarPath){
        File jar = new File(jarPath);
        URI uri = jar.toURI();
        String moduleName = jarPath.substring(jarPath.lastIndexOf(File.separatorChar)+1, jarPath.lastIndexOf("."));
        try {

            if(ClassloaderResponsity.getInstance().containsClassLoader(moduleName)){
                ClassloaderResponsity.getInstance().removeClassLoader(moduleName);
            }

            ModuleClassLoader classLoader = new ModuleClassLoader(new URL[]{uri.toURL()});
            SpringContextUtil.getBeanFactory().setBeanClassLoader(classLoader);
            Thread.currentThread().setContextClassLoader(classLoader);
            // classLoader.initRegisterSpringBean();
            ClassloaderResponsity.getInstance().addClassLoader(moduleName,classLoader);

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return SpringContextUtil.getAllBean();
    }

    @GetMapping(value = "/invoke")
    public Object invokeBean(String beanName){
        Method method = ReflectionUtils.findMethod(SpringContextUtil.getBean(beanName).getClass(), "users");
        Object result = ReflectionUtils.invokeMethod(method, SpringContextUtil.getBean(beanName));
        return result;
    }

    @GetMapping(value = "/getAll")
    public Object invokeTeacherBean(String beanName){
        Method method = ReflectionUtils.findMethod(SpringContextUtil.getBean(beanName).getClass(), "getAll");
        Object result = ReflectionUtils.invokeMethod(method, SpringContextUtil.getBean(beanName));
        return result;
    }

}
